package com.zbkj.crmeb.store.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.constants.Constants;
import com.utils.CrmebUtil;
import com.utils.vo.dateLimitUtilVo;
import com.zbkj.crmeb.store.model.StoreOrder;
import com.zbkj.crmeb.store.service.CustomerInsightService;
import com.zbkj.crmeb.store.service.StoreOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Service
public class CustomerInsightServiceImpl implements CustomerInsightService {

    @Autowired
    private StoreOrderService storeOrderService;

    /**
     * 功能描述: 指定时间的购买间隔 购买频次数据
     * @Param: [date, type, merId]
     * @Return: java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.Object>>
     * @Author: wangzh
     * @Date: 2023/1/8 10:21
     */
    @Override
    public Map<String, Map<String, Map<String, Object>>> getAnalysis(String date, String type, Integer merId) {
        Map<String, Map<String, Map<String, Object>>> response = new LinkedHashMap<>();
        //购买间隔在30天内的
        String startTime = LocalDate.parse(date).minusDays(30).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_END));
        String endTime = LocalDate.parse(date).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_END));
        List<StoreOrder> storeOrders = getDataByDate(new dateLimitUtilVo(startTime, endTime), merId);
        Map<String, Map<String, Object>> one = splicingResponse(storeOrders, type);
        response.put("R<30", one);
        //30≤R<90
        endTime = startTime;
        startTime = LocalDate.parse(date).minusDays(90).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_END));
        storeOrders = getDataByDate(new dateLimitUtilVo(startTime, endTime), merId);
        Map<String, Map<String, Object>> two = splicingResponse(storeOrders, type);
        response.put("30≤R<90", two);
        //90≤R<180
        endTime = startTime;
        startTime = LocalDate.parse(date).minusDays(180).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_END));
        storeOrders = getDataByDate(new dateLimitUtilVo(startTime, endTime), merId);
        Map<String, Map<String, Object>> three = splicingResponse(storeOrders, type);
        response.put("90≤R<180", three);
        //180≤R<365
        endTime = startTime;
        startTime = LocalDate.parse(date).minusDays(365).format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_END));
        storeOrders = getDataByDate(new dateLimitUtilVo(startTime, endTime), merId);
        Map<String, Map<String, Object>> four = splicingResponse(storeOrders, type);
        response.put("180≤R<365", four);
        //R≥365
        endTime = startTime;
        startTime = LocalDate.MIN.format(DateTimeFormatter.ofPattern(Constants.DATE_FORMAT_DATE));
        storeOrders = getDataByDate(new dateLimitUtilVo(startTime, endTime), merId);
        Map<String, Map<String, Object>> five = splicingResponse(storeOrders, type);
        response.put("R≥365", five);
        //总计
        response.put("count", getColumnData(response, type));
        return response;
    }

    /**
     * 功能描述: 获取指定日期内 用户购买次数与累计支付金额
     * @Param: [dateLimit, merId]
     * @Return: java.util.List<com.zbkj.crmeb.store.model.StoreOrder>
     * @Author: wangzh
     * @Date: 2023/1/8 10:33
     */
    private List<StoreOrder> getDataByDate(dateLimitUtilVo dateLimit, Integer merId){
        QueryWrapper<StoreOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("count(*) as id", "sum(pay_price) as pay_price")
                        .lambda().eq(StoreOrder::getMerId, merId)
                        .eq(StoreOrder::getPaid, 1)
                        .between(StoreOrder::getCreateTime, dateLimit.getStartTime(), dateLimit.getEndTime())
                        .groupBy(StoreOrder::getUid);
        return storeOrderService.list(queryWrapper);
    }

    /**
     * 功能描述: 返回RF分析一行的map
     * @Param: [storeOrders]
     * @Return: java.util.Map
     * @Author: wangzh
     * @Date: 2023/1/8 11:41
     */
    private Map<String, Map<String, Object>> splicingResponse(List<StoreOrder> storeOrders, String type){
        //购买频次对应的用户数
        int frequencyOneNumber = 0;
        int frequencyTwoNumber = 0;
        int frequencyThreeNumber = 0;
        int frequencyFourNumber = 0;
        int frequencyFiveNumber = 0;
        //购买频次对应的累计支付金额
        BigDecimal frequencyOnePrice = BigDecimal.ZERO;
        BigDecimal frequencyTwoPrice = BigDecimal.ZERO;
        BigDecimal frequencyThreePrice = BigDecimal.ZERO;
        BigDecimal frequencyFourPrice = BigDecimal.ZERO;
        BigDecimal frequencyFivePrice = BigDecimal.ZERO;
        //购买频次对应的订单数
        int frequencyOneOrderNumber = 0;
        int frequencyTwoOrderNumber = 0;
        int frequencyThreeOrderNumber = 0;
        int frequencyFourOrderNumber = 0;
        int frequencyFiveOrderNumber = 0;
        String key1 = null;
        String key2 = null;
        String key3 = null;
        String key4 = null;
        String key5 = null;
        if (type.equals("RF")){
            key1 = "F≥5";
            key2 = "F=4";
            key3 = "F=3";
            key4 = "F=2";
            key5 = "F=1";
        } else if (type.equals("RM")) {
            key1 = "M≥2000";
            key2 = "1000≤M<2000";
            key3 = "500≤M<1000";
            key4 = "200≤M<500";
            key5 = "M<200";
        }
        //遍历每个用户
        for (StoreOrder storeOrder : storeOrders){
            if (type.equals("RF")){
                if (storeOrder.getId() == 1){
                    frequencyFiveNumber ++;
                    frequencyFiveOrderNumber += storeOrder.getId();
                    frequencyFivePrice = frequencyFivePrice.add(storeOrder.getPayPrice());
                } else if (storeOrder.getId() == 2) {
                    frequencyFourNumber ++;
                    frequencyFourOrderNumber += storeOrder.getId();
                    frequencyFourPrice = frequencyFourPrice.add(storeOrder.getPayPrice());
                } else if (storeOrder.getId() == 3) {
                    frequencyThreeNumber ++;
                    frequencyThreeOrderNumber += storeOrder.getId();
                    frequencyThreePrice = frequencyThreePrice.add(storeOrder.getPayPrice());
                } else if (storeOrder.getId() == 4) {
                    frequencyTwoNumber ++;
                    frequencyTwoOrderNumber += storeOrder.getId();
                    frequencyTwoPrice = frequencyTwoPrice.add(storeOrder.getPayPrice());
                } else if (storeOrder.getId() >= 5) {
                    frequencyOneNumber ++;
                    frequencyOneOrderNumber += storeOrder.getId();
                    frequencyOnePrice = frequencyOnePrice.add(storeOrder.getPayPrice());
                }
            } else if (type.equals("RM")){
                if (storeOrder.getPayPrice().compareTo(new BigDecimal(2000)) >= 0){
                    frequencyOneNumber ++;
                    frequencyOneOrderNumber += storeOrder.getId();
                    frequencyOnePrice = frequencyOnePrice.add(storeOrder.getPayPrice());
                } else if (storeOrder.getPayPrice().compareTo(new BigDecimal(1000)) >= 0 && storeOrder.getPayPrice().compareTo(new BigDecimal(2000)) < 0){
                    frequencyTwoNumber ++;
                    frequencyTwoOrderNumber += storeOrder.getId();
                    frequencyTwoPrice = frequencyTwoPrice.add(storeOrder.getPayPrice());
                }  else if (storeOrder.getPayPrice().compareTo(new BigDecimal(500)) >= 0 && storeOrder.getPayPrice().compareTo(new BigDecimal(1000)) < 0) {
                    frequencyThreeNumber ++;
                    frequencyThreeOrderNumber += storeOrder.getId();
                    frequencyThreePrice = frequencyThreePrice.add(storeOrder.getPayPrice());
                } else if (storeOrder.getPayPrice().compareTo(new BigDecimal(200)) >= 0 && storeOrder.getPayPrice().compareTo(new BigDecimal(500)) < 0){
                    frequencyFourNumber ++;
                    frequencyFourOrderNumber += storeOrder.getId();
                    frequencyFourPrice = frequencyFourPrice.add(storeOrder.getPayPrice());
                } else if (storeOrder.getPayPrice().compareTo(new BigDecimal(200)) < 0){
                    frequencyFiveNumber ++;
                    frequencyFiveOrderNumber += storeOrder.getId();
                    frequencyFivePrice = frequencyFivePrice.add(storeOrder.getPayPrice());
                }
            }
        }
        Map<String, Map<String, Object>> map = new LinkedHashMap<>();
        BigDecimal customerUnitPriceOne = CrmebUtil.getCustomerUnitPrice(frequencyOnePrice, frequencyOneOrderNumber);
        map.put(key1, createMap(frequencyOneNumber, frequencyOnePrice, customerUnitPriceOne));
        BigDecimal customerUnitPriceTwo = CrmebUtil.getCustomerUnitPrice(frequencyTwoPrice, frequencyTwoOrderNumber);
        map.put(key2, createMap(frequencyTwoNumber, frequencyTwoPrice, customerUnitPriceTwo));
        BigDecimal customerUnitPriceThree = CrmebUtil.getCustomerUnitPrice(frequencyThreePrice, frequencyThreeOrderNumber);
        map.put(key3, createMap(frequencyThreeNumber, frequencyThreePrice, customerUnitPriceThree));
        BigDecimal customerUnitPriceFour = CrmebUtil.getCustomerUnitPrice(frequencyFourPrice, frequencyFourOrderNumber);
        map.put(key4, createMap(frequencyFourNumber, frequencyFourPrice, customerUnitPriceFour));
        BigDecimal customerUnitPriceFive = CrmebUtil.getCustomerUnitPrice(frequencyFivePrice, frequencyFiveOrderNumber);
        map.put(key5, createMap(frequencyFiveNumber, frequencyFivePrice, customerUnitPriceFive));
        map.put("count", createMap(frequencyFiveNumber + frequencyFourNumber + frequencyThreeNumber + frequencyTwoNumber + frequencyOneNumber, frequencyFivePrice.add(frequencyFourPrice).add(frequencyThreePrice).add(frequencyTwoPrice).add(frequencyOnePrice), customerUnitPriceFive.add(customerUnitPriceFour).add(customerUnitPriceThree).add(customerUnitPriceTwo).add(customerUnitPriceOne)));
        return map;
    }

    /**
     * 功能描述: 获取每一列数据
     * @Param: [map]
     * @Return: java.util.Map<java.lang.String,java.util.Map<java.lang.String,java.lang.Object>>
     * @Author: wangzh
     * @Date: 2023/1/8 15:39
     */
    private Map<String, Map<String, Object>> getColumnData(Map<String, Map<String, Map<String, Object>>> map, String type){
        //用户数列统计
        int fiveUserNumber = 0;
        int fourUserNumber = 0;
        int threeUserNumber = 0;
        int twoUserNumber = 0;
        int oneUserNumber = 0;
        //累计金额列统计
        BigDecimal fiveCumulativePayPrice = BigDecimal.ZERO;
        BigDecimal fourCumulativePayPrice = BigDecimal.ZERO;
        BigDecimal threeCumulativePayPrice = BigDecimal.ZERO;
        BigDecimal twoCumulativePayPrice = BigDecimal.ZERO;
        BigDecimal oneCumulativePayPrice = BigDecimal.ZERO;
        //客单价列统计
        BigDecimal fiveCustomerUnitPrice = BigDecimal.ZERO;
        BigDecimal fourCustomerUnitPrice = BigDecimal.ZERO;
        BigDecimal threeCustomerUnitPrice = BigDecimal.ZERO;
        BigDecimal twoCustomerUnitPrice = BigDecimal.ZERO;
        BigDecimal oneCustomerUnitPrice = BigDecimal.ZERO;
        String key1 = null;
        String key2 = null;
        String key3 = null;
        String key4 = null;
        String key5 = null;
        if (type.equals("RF")){
            key1 = "F=1";
            key2 = "F=2";
            key3 = "F=3";
            key4 = "F=4";
            key5 = "F≥5";
        } else if (type.equals("RM")) {
            key1 = "M<200";
            key2 = "200≤M<500";
            key3 = "500≤M<1000";
            key4 = "1000≤M<2000";
            key5 = "M≥2000";
        }
        Map<String, Map<String, Object>> returnMap = new LinkedHashMap<>();
        returnMap.put(key5, createMap(fiveUserNumber, fiveCumulativePayPrice, fiveCustomerUnitPrice));
        returnMap.put(key4, createMap(fourUserNumber, fourCumulativePayPrice, fourCustomerUnitPrice));
        returnMap.put(key3, createMap(threeUserNumber, threeCumulativePayPrice, threeCustomerUnitPrice));
        returnMap.put(key2, createMap(twoUserNumber, twoCumulativePayPrice, twoCustomerUnitPrice));
        returnMap.put(key1, createMap(oneUserNumber, oneCumulativePayPrice, oneCustomerUnitPrice));
        returnMap.put("count", createMap(fiveUserNumber, fiveCumulativePayPrice, fiveCustomerUnitPrice));
        for (Map.Entry<String, Map<String, Map<String, Object>>> entry : map.entrySet()){
            for (Map.Entry<String, Map<String, Object>> entry1 : entry.getValue().entrySet()){
                Map<String, Object> map1 = returnMap.get(entry1.getKey());
                map1.put("userNumber", (Integer) map1.get("userNumber") + (Integer) entry1.getValue().get("userNumber"));
                map1.put("cumulativePayPrice", ((BigDecimal) map1.get("cumulativePayPrice")).add((BigDecimal) entry1.getValue().get("cumulativePayPrice")));
                map1.put("customerUnitPrice", ((BigDecimal) map1.get("customerUnitPrice")).add((BigDecimal) entry1.getValue().get("customerUnitPrice")));
            }
        }
        return returnMap;
    }

    /**
     * 功能描述: 创建相同map
     * @Param: [number, price, customerUnitPrice]
     * @Return: java.util.Map<java.lang.String,java.lang.Object>
     * @Author: wangzh
     * @Date: 2023/1/9 10:30
     */
    private Map<String, Object> createMap(Integer number, BigDecimal price, BigDecimal customerUnitPrice){
        Map<String, Object> map = new HashMap<>();
        map.put("userNumber", number);
        map.put("cumulativePayPrice", price);
        map.put("customerUnitPrice", customerUnitPrice);
        return map;
    }
}
